package com.miukoo.aikao.metadata.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.miukoo.aikao.core.dtos.ApiResult;
import com.miukoo.aikao.core.dtos.PageReqDto;
import com.miukoo.aikao.core.dtos.PageResDto;
import com.miukoo.aikao.core.enums.ApiError;
import com.miukoo.aikao.core.exceptions.ApiException;
import com.miukoo.aikao.core.utils.ApiUtils;
import com.miukoo.aikao.core.utils.BeanMapperUtils;
import com.miukoo.aikao.core.utils.StringUtils;
import com.miukoo.aikao.core.utils.passwd.PassHandler;
import com.miukoo.aikao.core.utils.passwd.PassInfo;
import com.miukoo.aikao.metadata.api.v1.SysUserApi;
import com.miukoo.aikao.metadata.dto.SysUserDto;
import com.miukoo.aikao.metadata.dto.request.SysUserSaveReqDto;
import com.miukoo.aikao.metadata.mapper.SysUserMapper;
import com.miukoo.aikao.metadata.pojos.SysUser;
import com.miukoo.aikao.metadata.service.SysUserRoleService;
import com.miukoo.aikao.metadata.service.SysUserService;
import org.apache.sshd.common.config.keys.loader.openssh.kdf.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService, SysUserApi {

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private ObjectMapper objectMapper;

    private BCrypt bCrypt = new BCrypt();


    @Override
    public PageResDto<List<SysUser>> paging(PageReqDto<SysUserDto> reqDto) {

        //创建分页对象
        IPage<SysUser> query = new Page<>(reqDto.getCurrent(), reqDto.getSize());

        //查询条件
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();

        SysUserDto params = reqDto.getParams();

        if(params!=null){
            if(!StringUtils.isBlank(params.getUserName())){
                wrapper.lambda().like(SysUser::getUserName, params.getUserName());
            }

            if(!StringUtils.isBlank(params.getRealName())){
                wrapper.lambda().like(SysUser::getRealName, params.getRealName());
            }
        }

        //获得数据
        IPage<SysUser> page = this.page(query, wrapper);
        return PageResDto.result(page.getTotal(),page.getRecords());
     }

    @Override
    public SysUser findByName(String userName) {

        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SysUser::getUserName, userName);

        SysUser user = this.getOne(wrapper, false);
        return user;
    }

    /**
     * 修改用户昵称、头像、密码
     * @param reqDto
     * @param userId
     * @return
     */
    @Override
    public ApiResult update(SysUserDto reqDto, Long userId) {
        SysUser user = this.getById(userId);
        String pass = reqDto.getPassword();
        if(!StringUtils.isBlank(pass)){
            if(BCrypt.checkpw(reqDto.getOldPassword(),user.getPassword())) {
                String salt = BCrypt.gensalt();
                String password = BCrypt.hashpw(pass, salt);
                user.setPassword(password);
                user.setSalt(salt);
            }else{
                return ApiUtils.failure("原密码错误！");
            }
        }
        user.setUserName(reqDto.getUserName());
        user.setAvatar(reqDto.getAvatar());
        this.updateById(user);
        return ApiUtils.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(SysUserSaveReqDto reqDto) {

        List<String> roles = reqDto.getRoles();

        if(CollectionUtils.isEmpty(roles)){
            throw new ApiException(ApiError.ERROR_90010003);
        }

        // 保存基本信息
        SysUser user = new SysUser();
        BeanMapperUtils.copy(reqDto, user);

        // 添加模式
        if(user.getId()==null){
            user.setId(Long.valueOf(IdWorker.getIdStr()));
        }

        // 修改密码
        if(!StringUtils.isBlank(reqDto.getPassword())){
            PassInfo pass = PassHandler.buildPassword(reqDto.getPassword());
            user.setPassword(pass.getPassword());
            user.setSalt(pass.getSalt());
        }

        // 保存角色信息
        String roleIds = sysUserRoleService.saveRoles(user.getId(), roles);
        user.setRoleIds(roleIds);
        this.saveOrUpdate(user);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public SysUser reg(SysUserDto reqDto) {

        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SysUser::getUserName, reqDto.getUserName());

        int count = this.count(wrapper);

        if(count > 0){
            throw new ApiException(1, "用户名已存在，换一个吧！");
        }


        // 保存用户
        SysUser user = new SysUser();
        user.setId(Long.valueOf(IdWorker.getIdStr()));
        user.setUserName(reqDto.getUserName());
        user.setRealName(reqDto.getRealName());
        String salt = BCrypt.gensalt();
        user.setPassword(BCrypt.hashpw(reqDto.getPassword(),salt));
        user.setSalt(salt);
        user.setDepartId(reqDto.getDepartId());

        // 保存角色
        List<String> roles = new ArrayList<>();
        roles.add("student");
        String roleIds = sysUserRoleService.saveRoles(user.getId(), roles);
        user.setRoleIds(roleIds);
        this.save(user);

        return user;
    }

    @Override
    public SysUser quickReg(SysUserDto reqDto) {

        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SysUser::getUserName, reqDto.getUserName());
        wrapper.last(" LIMIT 1 ");
        SysUser user = this.getOne(wrapper);
        return this.reg(reqDto);
    }


    @Override
    public SysUser getByUserId(Long userId) {
        return getById(userId);
    }
}
